package com.lebang.medicalInquiry.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.Text;
import com.alipay.api.domain.UserVo;
import com.lebang.medicalInquiry.component.RedisComponent;
import com.lebang.medicalInquiry.component.TokenComponent;
import com.lebang.medicalInquiry.constant.ConsultationScheduleEnum;
import com.lebang.medicalInquiry.constant.RedisKeyEnum;
import com.lebang.medicalInquiry.constant.ResponseEnum;
import com.lebang.medicalInquiry.constant.annotation.RateLimit;
import com.lebang.medicalInquiry.constant.annotation.Require;
import com.lebang.medicalInquiry.exception.BusinessException;
import com.lebang.medicalInquiry.handler.LiveMessageHandler;
import com.lebang.medicalInquiry.handler.MessageHandler;
import com.lebang.medicalInquiry.model.dto.UserTokenDto;
import com.lebang.medicalInquiry.model.po.*;
import com.lebang.medicalInquiry.model.vo.*;
import com.lebang.medicalInquiry.response.Callback;
import com.lebang.medicalInquiry.response.JsonData;
import com.lebang.medicalInquiry.service.PhysicianService;
import com.lebang.medicalInquiry.service.UserService;
import com.lebang.medicalInquiry.utils.*;
import com.lebang.medicalInquiry.utils.shengwang.RtcTokenBuilder2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;

@RequestMapping("/api/user")
@Api(tags = "用户相关")
@RestController
@Validated
public class UserApi {

    @Autowired
    private UserService userService;

    @Autowired
    private TokenComponent tokenComponent;

    @Autowired
    private RedisComponent redisComponent;

    @Autowired
    private LiveMessageHandler messageHandler;

    @Autowired
    private PhysicianService physicianService;

    @Value("${digital.merchant_id}")
    private String merchantId;


    @ApiOperation("根据不同类型进行登录验证")
    @RateLimit(key = "login:", capacity = 10, requestedTokens = 10)
    @PostMapping("/login")
    public JsonData login(HttpServletRequest request, HttpServletResponse response
            , @ApiParam(name = "phone", value = "手机号", required = true) @NotBlank(message = "手机号不能为空") @RequestParam(required = false) String phone
            , @ApiParam(name = "code", value = "登录验证码") @RequestParam(required = false, name = "code") String code
    ) {
        Object value = redisComponent.getValue(RedisKeyEnum.login_code.getName() + phone);
        if (TextUtil.isEmpty(value) || !value.equals(code)) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), "验证码错误");
        }

        String ip = IpUtil.getIp(request);

        UserTokenDto userTokenDTO = userService.login(phone, ip);

        UserInfoVo userVo = userTokenDTO.getUserVo();

        String token = tokenComponent.getToken(UserTokenVo.builder().id(userVo.getId()).uuid(userVo.getUuid()).build());

        response.setHeader("token", token);

        redisComponent.setExTimeValue(RedisKeyEnum.user_tokens.getName() + token, userVo, 60 * 60 * 24 * 7);

        return Callback.success(ResponseEnum.SUCCESS.getCode(), "登录成功", userVo);
    }

    @Require
    @PutMapping("/info")
    @ApiOperation("修改用户信息")
    public JsonData liveChat(HttpServletRequest request, HttpServletResponse response,
                                                  @ApiParam(name = "user", value = "用户相关信息")
                                                  @RequestBody User user) {
        String uuid = request.getAttribute("uuid").toString();
        user.setUuid(uuid);
        userService.modifyUserInfo(user);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());

    }

    @Require
    @GetMapping("/patient")
    @ApiOperation("查询就诊人")
    public JsonData<List<UserPatient>> getUserPatientList(HttpServletRequest request, HttpServletResponse response,
                                                          @ApiParam(name = "page", value = "页码")
                                                          @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                                          @ApiParam(name = "limit", value = "条数")
                                                          @RequestParam(value = "limit", required = false, defaultValue = "1") Integer limit) {
        String uuid = request.getAttribute("uuid").toString();

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.getUserPatientList(uuid, page, limit));

    }

    @Require
    @PutMapping("/patient")
    @ApiOperation("修改就诊人")
    public JsonData modifyUserPatient(HttpServletRequest request, HttpServletResponse response,
                                      @RequestBody UserPatient userPatient) {
        String uuid = request.getAttribute("uuid").toString();
        if (userPatient == null) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), null);
        }
        userService.modifyUserPatient(uuid, userPatient);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());

    }

    @Require
    @DeleteMapping("/patient/{userPatientId}")
    @ApiOperation("删除就诊人")
    public JsonData removeUserPatient(HttpServletRequest request, HttpServletResponse response,
                                      @ApiParam(name = " userPatientId", value = "就诊人id") @NotNull(message = "userPatientId 不能为空")
                                      @PathVariable(value = "userPatientId") Integer userPatientId) {
        String uuid = request.getAttribute("uuid").toString();

        userService.removeUserPatient(uuid, userPatientId);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());

    }

    @Require
    @GetMapping("/patient/case")
    @ApiOperation("查询就诊人病例文件")
    public JsonData<List<UserPatientCaseFile>> getUserPatientCaseFileList(HttpServletRequest request, HttpServletResponse response,
                                                                          @ApiParam(name = "patientId", value = "就诊人员id")
                                                                          @RequestParam(value = "patientId", required = false) Integer patientId,
                                                                          @ApiParam(name = "page", value = "页码")
                                                                          @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                                                          @ApiParam(name = "limit", value = "条数")
                                                                          @RequestParam(value = "limit", required = false, defaultValue = "1") Integer limit) {
        String uuid = request.getAttribute("uuid").toString();

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.getUserPatientCaseFileList(uuid, patientId, page, limit));

    }

    @Require
    @PutMapping("/patient/case")
    @ApiOperation("修改就诊人病例文件")
    public JsonData modifyUserPatientCaseFile(HttpServletRequest request, HttpServletResponse response,
                                              @RequestBody UserPatientCaseFile userPatientCaseFile) {
        String uuid = request.getAttribute("uuid").toString();
        if (userPatientCaseFile == null) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), null);
        }

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.modifyUserPatientCaseFile(uuid, userPatientCaseFile));

    }

    @Require
    @DeleteMapping("/patient/case/{physicianCaseFileId}")
    @ApiOperation("删除就诊人病例文件")
    public JsonData removeUserPatientCaseFile(HttpServletRequest request, HttpServletResponse response,
                                              @ApiParam(name = "physicianCaseFileId", value = "病例文件id") @NotNull(message = "physicianCaseFileId 不能为空")
                                              @PathVariable(value = "physicianCaseFileId") Integer physicianCaseFileId) {
        String uuid = request.getAttribute("uuid").toString();

        userService.removeUserPatientCaseFile(uuid, physicianCaseFileId);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());

    }

    @Require
    @GetMapping("/consultation/info/{sheetId}")
    @ApiOperation("查询问诊单的详情")
    public JsonData<ConsultationSheet> getUserConsultationList(HttpServletRequest request, HttpServletResponse response,
                                                                                     @ApiParam(name = "sheetId", value = "问诊单的id") @NotNull(message = "sheetId 问诊单id不允许为空")
                                                                                     @PathVariable(value = "sheetId") Integer sheetId) {
        String uuid = request.getAttribute("uuid").toString();

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.getUserConsultationInfo(sheetId));

    }

    @Require
    @GetMapping("/consultation/schedule/info/{sheetId}")
    @ApiOperation("查询问诊单的进度详情")
    public JsonData<List<ConsultationSheetSchedule>> getUserConsultationScheduleList(HttpServletRequest request, HttpServletResponse response,
                                                                                     @ApiParam(name = "sheetId", value = "问诊单的id") @NotNull(message = "sheetId 问诊单id不允许为空")
                                                                                     @PathVariable(value = "sheetId") Integer sheetId) {
        String uuid = request.getAttribute("uuid").toString();

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.getUserConsultationScheduleList(uuid, sheetId));

    }

    @Require
    @GetMapping("/consultation/sheet")
    @ApiOperation("查询问诊单列表(根据结束状态倒序排序)")
    public JsonData<List<ConsultationSheetInfoVo>> getUserConsultationSheetInfo(HttpServletRequest request, HttpServletResponse response,
                                                                            @ApiParam(name = "page", value = "页码")
                                                                            @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                                                            @ApiParam(name = "limit", value = "条数")
                                                                            @RequestParam(value = "limit", required = false, defaultValue = "1") Integer limit) {
        String uuid = request.getAttribute("uuid").toString();

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), userService.getUserConsultationSheetList(uuid, page, limit));

    }


    @RateLimit(key = "update_consultation_sheet:", capacity = 2, requestedTokens = 2)
    @Require
    @ApiOperation("添加对应的问诊单进度")
    @PutMapping(value = "/consultation/schedule")
    public JsonData modifyConsultationSheet(HttpServletRequest request, HttpServletResponse response,
                                            @RequestBody ConsultationSheetSchedule consultationSheetSchedule
    ) {


        String uuid = request.getAttribute("uuid").toString();
        Integer consultationSheetId = consultationSheetSchedule.getConsultationSheetId();
        ConsultationSheet consultationSheet = userService.getConsultationSheetById(consultationSheetId);

        if (consultationSheetSchedule.getConsultationSheetId() == null) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), "问诊单id为空");
        }
        if (!consultationSheet.getUuid().equals(uuid)) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), "当前问诊单非当前用户所属");
        }

        // 获取当前问诊的进度
        ConsultationScheduleEnum nowStep = ConsultationScheduleEnum.valueOf(consultationSheet.getScheduleState());

        if (!ConsultationScheduleEnum.settle_bill.getCode().equals(nowStep.getCode())) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), "只有当问诊单进度为结算中,用户才允许操作");
        }
        if (ConsultationScheduleEnum.end.getCode().equals(nowStep.getCode())) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), "问诊单流程已结束,请勿重复操作");
        }
        // 获取要修改的问诊进度
        ConsultationScheduleEnum nextStep = ConsultationScheduleEnum.valueOf(consultationSheetSchedule.getScheduleState());
        if (!ConsultationScheduleEnum.end.getCode().equals(nextStep.getCode())) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), ResponseEnum.FAIL.getMemo(), "用户只能结束问诊单");
        }

        userService.addConsultationSheet(consultationSheet, consultationSheetSchedule);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());

    }

    @Require
    @RateLimit(key = "user_live_chat:",requestedTokens = 2,capacity = 2)
    @PostMapping("/live/chat")
    @ApiOperation("直播弹幕发送")
    public JsonData liveChat(HttpServletRequest request, HttpServletResponse response,
                                                  @ApiParam(name = "messageModel", value = "消息发送实体")
                                                  @RequestBody MessageModel messageModel) {
        String liveRoomId = messageModel.getLiveRoomId();
        if (TextUtil.isEmpty(liveRoomId)) {
            return Callback.fail(ResponseEnum.FAIL.getCode(), "liveRoomId 必传");
        }
        boolean b = messageHandler.liveChat(messageModel);
        if(b){
            Physician physician = physicianService.getByLiveRoomId(liveRoomId);
            if(physician!=null){
                DigitalMataHttpUtil.liveChat(physician.getProjectId(),merchantId,"",messageModel.getContent(),physician.getLiveRoomId(),messageModel.getFromUuid());
            }

            return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo());
        }

        return  Callback.fail(ResponseEnum.FAIL.getCode(), "直播间不存在");

    }

    @Require
    @PostMapping("/live/room/num/{roomId}")
    @ApiOperation("直播间人数")
    public JsonData  liveChat(HttpServletRequest request, HttpServletResponse response,@PathVariable String roomId) {




        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), messageHandler.getLiveRoomNum(roomId));

    }
}
